﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using LinkDownloader.Core;
using LinkDownloader.DownloadManger;

namespace LinkDownloader.Forms
{
    internal partial class frmSplash : Form
    {

        private BackgroundWorker worker = null;
        private bool close = false;

        private volatile bool busy = false;
        public bool Busy
        {
            get { return this.busy; }
        }

        private volatile int progress = 0;
        public int Progress
        {
            get { return this.progress; }
        }

        private volatile string status = string.Empty;
        public string Status
        {
            get { return this.status; }
        }
        
        private MainDownloader downloader = null;

        public frmSplash()
        {

            InitializeComponent();

            this.worker = new BackgroundWorker();
            this.worker.WorkerReportsProgress = false;
            this.worker.WorkerSupportsCancellation = false;

            this.worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            this.worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

        }
                
        public frmSplash(MainDownloader downloader)
            : this()
        {

            this.downloader = downloader;

        }

        private static void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            frmSplash splash = e.Argument as frmSplash;
            splash.StartLoading(splash);
            e.Result = splash;
        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            frmSplash splash = e.Result as frmSplash;
            splash.EndSplash(null);
        }

        private void StartSplash()
        {
            this.busy = true;
            this.worker.RunWorkerAsync(this);
        }

        private void EndSplash(object args)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ChangeCallBack(EndSplash), args);
            }
            else
            {
                this.Hide();
                this.downloader.Form.Show();
            }
        }

        private void StartLoading(object args)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ChangeCallBack(StartLoading), args);
            }
            else
            {
                frmSplash splash = args as frmSplash;
                splash.downloader.Form.DoSplashInitialization(this);
            }
        }

        public void EndLoading()
        {
            this.busy = false;
        }

        private void UpdateProgressbar(object arg)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ChangeCallBack(UpdateProgressbar), arg);
            }
            else
            {
                int p = this.progress - this.progressBar.Value;
                this.progressBar.Increment(p);
                if (this.lblStatus.Text != this.status)
                {
                    this.lblStatus.Text = this.status;
                    Application.DoEvents();
                }
            }
        }

        private void frmSplash_Load(object sender, EventArgs e)
        {
            this.timerLoading.Enabled = true;
        }

        private void timerLoading_Tick(object sender, EventArgs e)
        {
            this.downloader.Form = new frmMain(this.downloader);
            this.StartSplash();
            this.timerLoading.Enabled = false;
        }

        public void UpdateProgress(int value)
        {
            this.progress = value;
            this.UpdateProgressbar(null);
        }

        public void UpdateProgress(int value, string status)
        {
            this.progress = value;
            this.status = status;
            this.UpdateProgressbar(null);
        }

        public void ForceClose()
        {
            this.close = true;
            this.Close();
            this.close = false;
        }

        private void frmSplash_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!this.close) { e.Cancel = true; }
        }
                
    }
}
